home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1997 December / MACPOWER-1997-12.ISO.7z / MACPOWER-1997-12.ISO / AMUG / PROGRAMMING / Raven 1.2.sit / Raven 1.2 / Source / Foundation / OS / ZPointer.cpp < prev    next >
Text File  |  1997-06-18  |  8KB  |  366 lines

  1. /*
  2.  *  File:        ZPointer.h
  3.  *  Summary:    A class to encapsulate non-relocatable memory.
  4.  *  Written by:    Jesse Jones
  5.  *
  6.  *  Copyright ゥ 1996-1997 Jesse Jones. 
  7.  *    For conditions of distribution and use, see copyright notice in ZTypes.h  
  8.  *
  9.  *  Change History (most recent first):
  10.  *
  11.  *         <2>     5/29/97    JDJ        No longer uses NewPtr for big blocks.
  12.  *         <1>     1/14/96    JDJ        Created.
  13.  */
  14.  
  15. #include <ZPointer.h>
  16.  
  17. #include <ZDebug.h>
  18. #include <ZExceptions.h>
  19. #include <ZMemUtils.h>
  20. #include <ZMiscUtils.h>
  21. #include <ZReferenceCounted.h>
  22.  
  23.  
  24. // ===================================================================================
  25. //    Helper Functions
  26. // ===================================================================================
  27.  
  28. //---------------------------------------------------------------
  29. //
  30. // Min
  31. //
  32. //---------------------------------------------------------------
  33. inline ulong Min(ulong x, ulong y)
  34. {
  35.     if (x <= y)
  36.         return x;
  37.     else
  38.         return y;
  39. }
  40.  
  41. #pragma mark -
  42.  
  43. // ===================================================================================
  44. //    class ZPointerRef
  45. // ===================================================================================
  46. class ZPointerRef : public MReferenceCounted {
  47.  
  48.     friend TPointer;
  49.  
  50. public:
  51.                         ~ZPointerRef();
  52.  
  53.                         ZPointerRef();
  54.                         // Creates a nil pointer.
  55.  
  56.                         ZPointerRef(ulong bytes, bool zeroBytes);
  57.                         
  58.                         ZPointerRef(Ptr takePtr);
  59.  
  60.             const Byte* GetPtr() const;
  61.  
  62.             Byte*         GetPtr();
  63.  
  64.             ulong         GetSize() const;
  65.  
  66.             void         SetSize(ulong bytes, bool zeroBytes);
  67.     
  68. private:
  69.                         ZPointerRef(const ZPointerRef& ref);
  70.                         
  71.                         ZPointerRef& operator=(const ZPointerRef& ref);
  72.  
  73. private:    
  74.     Byte*        mPtr;
  75.     ulong        mSize;
  76. };
  77.  
  78.  
  79. //---------------------------------------------------------------
  80. //
  81. // ZPointerRef::~ZPointerRef
  82. //
  83. //---------------------------------------------------------------
  84. ZPointerRef::~ZPointerRef()
  85. {
  86.     delete [] mPtr;
  87. }
  88.  
  89.  
  90. //---------------------------------------------------------------
  91. //
  92. // ZPointerRef::ZPointerRef ()
  93. //
  94. //---------------------------------------------------------------
  95. ZPointerRef::ZPointerRef()
  96. {
  97.     mPtr = nil;
  98.     mSize = 0;
  99. }
  100.  
  101.     
  102. //---------------------------------------------------------------
  103. //
  104. // ZPointerRef::ZPointerRef (ulong, bool)
  105. //
  106. //---------------------------------------------------------------
  107. ZPointerRef::ZPointerRef(ulong bytes, bool zeroBytes)
  108. {    
  109.     ASSERT(bytes < 16*1024L*1024L);
  110.     
  111.     mPtr = nil;
  112.     mSize = bytes;
  113.     
  114.     mPtr = new Byte[mSize];
  115.     if (zeroBytes)
  116.         ClearMemory(mPtr, mSize);
  117. }
  118.  
  119.  
  120. //---------------------------------------------------------------
  121. //
  122. // ZPointerRef::ZPointerRef (Ptr)
  123. //
  124. //---------------------------------------------------------------
  125. ZPointerRef::ZPointerRef(Ptr takePtr)
  126. {    
  127.     ASSERT(takePtr != nil);
  128.     
  129.     mPtr  = reinterpret_cast<Byte*>(takePtr);
  130.     mSize = (ulong) GetPtrSize(takePtr);
  131. }
  132.  
  133.  
  134. //---------------------------------------------------------------
  135. //
  136. // ZPointerRef::GetPtr const
  137. //
  138. //---------------------------------------------------------------
  139. inline const Byte* ZPointerRef::GetPtr() const
  140. {
  141.     ASSERT(mPtr != nil);
  142.     
  143.     return (Byte *) mPtr;
  144. }
  145.  
  146.  
  147. //---------------------------------------------------------------
  148. //
  149. // ZPointerRef::GetPtr
  150. //
  151. //---------------------------------------------------------------
  152. inline Byte* ZPointerRef::GetPtr()
  153. {
  154.     ASSERT(mPtr != nil);
  155.     
  156.     return (Byte *) mPtr;
  157. }
  158.  
  159.  
  160. //---------------------------------------------------------------
  161. //
  162. // ZPointerRef::GetSize
  163. //
  164. //---------------------------------------------------------------
  165. inline ulong ZPointerRef::GetSize() const
  166. {
  167.     return mSize;
  168. }
  169.  
  170.  
  171. //---------------------------------------------------------------
  172. //
  173. // ZPointerRef::SetSize
  174. //
  175. //---------------------------------------------------------------
  176. void ZPointerRef::SetSize(ulong bytes, bool zeroBytes)
  177. {
  178.     ASSERT(bytes < 16*1024L*1024L);
  179.     
  180.     if (bytes != mSize) {
  181.         Byte* newPtr = new Byte[bytes];            // Don't need a TRY block because this is the only thing that can fail.
  182.         
  183.         ulong validBytes = Min(bytes, mSize);
  184.         BlockMoveData(mPtr, newPtr, validBytes);
  185.  
  186.         delete [] mPtr;
  187.         mPtr = newPtr;
  188.         
  189.         if (zeroBytes && bytes > mSize)
  190.             ClearMemory(mPtr + mSize, bytes - mSize);
  191.  
  192.         mSize = bytes;
  193.     }
  194. }
  195.  
  196. #pragma mark -
  197.  
  198. // ===================================================================================
  199. //    class TPointer
  200. // ===================================================================================
  201.  
  202. //---------------------------------------------------------------
  203. //
  204. // TPointer::~TPointer
  205. //
  206. //---------------------------------------------------------------
  207. TPointer::~TPointer()
  208. {
  209.     mPointerRef->RemoveReference();
  210. }
  211.     
  212.  
  213. //---------------------------------------------------------------
  214. //
  215. // TPointer::TPointer (ulong, bool)
  216. //
  217. //---------------------------------------------------------------
  218. TPointer::TPointer(ulong bytes, bool zeroBytes)
  219. {
  220.     mPointerRef = new ZPointerRef(bytes, zeroBytes);
  221. }
  222.  
  223.  
  224. //---------------------------------------------------------------
  225. //
  226. // TPointer::TPointer (Ptr)
  227. //
  228. //---------------------------------------------------------------
  229. TPointer::TPointer(Ptr takePtr)
  230. {
  231.     try {
  232.         mPointerRef = new ZPointerRef(takePtr);
  233.         
  234.     } catch (...) {
  235.         DisposePtr(takePtr);
  236.         throw;
  237.     }
  238. }
  239.  
  240.  
  241. //---------------------------------------------------------------
  242. //
  243. // TPointer::TPointer (TPointer)
  244. //
  245. // Does a shallow copy so it's real fast.
  246. //
  247. //---------------------------------------------------------------
  248. TPointer::TPointer(const TPointer& rhs)
  249. {
  250.     mPointerRef = rhs.mPointerRef;
  251.     mPointerRef->AddReference();
  252. }
  253.  
  254.  
  255. //---------------------------------------------------------------
  256. //
  257. // TPointer::operator=
  258. //
  259. //---------------------------------------------------------------
  260. TPointer& TPointer::operator=(const TPointer& rhs)
  261. {
  262.     if (mPointerRef != rhs.mPointerRef) {
  263.         mPointerRef->RemoveReference();
  264.             
  265.         mPointerRef = rhs.mPointerRef;
  266.         mPointerRef->AddReference();
  267.     }
  268.     
  269.     return *this;
  270. }
  271.  
  272.  
  273. //---------------------------------------------------------------
  274. //
  275. // TPointer::Detach
  276. //
  277. //---------------------------------------------------------------
  278. void TPointer::Detach()
  279. {
  280.     if (mPointerRef->GetRefCount() > 1) {
  281.         ulong bytes = mPointerRef->GetSize();
  282.  
  283.         ZPointerRef* oldRef = mPointerRef;
  284.         ZPointerRef* newRef = new ZPointerRef(bytes, kDontZeroBytes);
  285.  
  286.         BlockMoveData(oldRef->GetPtr(), newRef->GetPtr(), bytes);
  287.  
  288.         mPointerRef->RemoveReference();
  289.         mPointerRef = newRef;
  290.     }
  291. }
  292.  
  293.  
  294. //---------------------------------------------------------------
  295. //
  296. // TPointer::GetPtr const
  297. //
  298. //---------------------------------------------------------------
  299. const Byte* TPointer::GetPtr() const
  300. {
  301.     const Byte* ptr = mPointerRef->GetPtr();
  302.  
  303.     return ptr;
  304. }
  305.  
  306.  
  307. //---------------------------------------------------------------
  308. //
  309. // TPointer::GetPtr
  310. //
  311. //---------------------------------------------------------------
  312. Byte* TPointer::GetPtr()
  313. {
  314.     Byte* ptr = mPointerRef->GetPtr();
  315.  
  316.     return ptr;
  317. }
  318.  
  319.  
  320. //---------------------------------------------------------------
  321. //
  322. // TPointer::GetSize
  323. //
  324. //---------------------------------------------------------------
  325. ulong TPointer::GetSize() const
  326. {
  327.     ulong size = mPointerRef->GetSize();
  328.     
  329.     return size;
  330. }
  331.  
  332.  
  333. //---------------------------------------------------------------
  334. //
  335. // TPointer::SetSize
  336. //
  337. //---------------------------------------------------------------
  338. void TPointer::SetSize(ulong bytes, bool zeroBytes)
  339. {
  340.     mPointerRef->SetSize(bytes, zeroBytes);
  341. }
  342.  
  343.  
  344. //---------------------------------------------------------------
  345. //
  346. // TPointer::operator==
  347. //
  348. //---------------------------------------------------------------
  349. bool TPointer::operator==(const TPointer& rhs) const
  350. {
  351.     bool equal = mPointerRef == rhs.mPointerRef;
  352.     
  353.     if (!equal) {
  354.         ulong crc1 = ComputeCRC(this->GetPtr(), this->GetSize());
  355.         ulong crc2 = ComputeCRC(rhs.GetPtr(), rhs.GetSize());
  356.         
  357.         equal = crc1 == crc2;
  358.     }
  359.     
  360.     return equal;
  361. }
  362.  
  363.  
  364.  
  365.  
  366.